#include "Switch.h"
#include "malloc.h"

#include <rtthread.h>
#include "user_led.h"
#include "stdbool.h"
#include "Model_info.h"
Switch_Model_t sw_model;
Switch_Retry_t sw_retry;

void Start_Switch_Response_Wait(Switch_Retry_t *retry);

void Send_Switch_Response(Chanle_IN_t status);
void Set_LED_DO(uint8_t led_idx,uint8_t status);

void Recive_Switch_Response(SW_Status status);   //接收响应
//用户接口，查询开关输入状态
Chanle_IN_t User_Get_Sw_status()
{
	return sw_model.SW_IN_Status;  
}
//用户查询继电器状态
Chanle_IN_t User_Get_Relay_status()
{
	return sw_model.SW_OUT_Status;
}
/// @brief 
/// @param status 状态
void OpenOFF_SW(SW_Status status)
{
	
	status.sw_in1==SW_ON?SW1_OUT_ON() :  SW1_OUT_OFF();
	status.sw_in2==SW_ON?SW2_OUT_ON() :  SW2_OUT_OFF();
	status.sw_in3==SW_ON?SW3_OUT_ON() :  SW3_OUT_OFF();
	status.sw_in4==SW_ON?SW4_OUT_ON() :  SW4_OUT_OFF();
	sw_model.SW_OUT_Status.IN1=status.sw_in1;
	sw_model.SW_OUT_Status.IN2=status.sw_in2;
	sw_model.SW_OUT_Status.IN3=status.sw_in3;
	sw_model.SW_OUT_Status.IN4=status.sw_in4;
	Send_Switch_Response(sw_model.SW_OUT_Status);
	Set_LED_DO(LED_IO1,sw_model.SW_OUT_Status.IN1);
	Set_LED_DO(LED_IO2,sw_model.SW_OUT_Status.IN2);
	Set_LED_DO(LED_IO3,sw_model.SW_OUT_Status.IN3);
	Set_LED_DO(LED_IO4,sw_model.SW_OUT_Status.IN4);
}

/// @brief 
/// @param status 状态
void OpenOFF_SW_NOResponse(SW_Status status)
{
	
	status.sw_in1==SW_ON?SW1_OUT_ON() :  SW1_OUT_OFF();
	status.sw_in2==SW_ON?SW2_OUT_ON() :  SW2_OUT_OFF();
	status.sw_in3==SW_ON?SW3_OUT_ON() :  SW3_OUT_OFF();
	status.sw_in4==SW_ON?SW4_OUT_ON() :  SW4_OUT_OFF();
	sw_model.SW_OUT_Status.IN1=status.sw_in1;
	sw_model.SW_OUT_Status.IN2=status.sw_in2;
	sw_model.SW_OUT_Status.IN3=status.sw_in3;
	sw_model.SW_OUT_Status.IN4=status.sw_in4;
	
	Set_LED_DO(LED_IO1,sw_model.SW_OUT_Status.IN1);
	Set_LED_DO(LED_IO2,sw_model.SW_OUT_Status.IN2);
	Set_LED_DO(LED_IO3,sw_model.SW_OUT_Status.IN3);
	Set_LED_DO(LED_IO4,sw_model.SW_OUT_Status.IN4);
}
//显示远程开关输出状态
void Set_LED_DO(uint8_t led_idx,uint8_t status)
{
	switch(led_idx)
	{
		case LED_IO1:status == SW_ON ? LED1_IO_ON() : LED1_IO_OFF();break;
		case LED_IO2:status == SW_ON ? LED2_IO_ON() : LED2_IO_OFF();break;
		case LED_IO3:status == SW_ON ? LED3_IO_ON() : LED3_IO_OFF();break;
		case LED_IO4:status == SW_ON ? LED4_IO_ON() : LED4_IO_OFF();break;
	}
}
/// @brief 反馈状态
/// @param status 状态
void SW_FB_Status(SW_Status status)
{
	status.relay_out1==SW_ON? LED1_FB_ON() : LED1_FB_OFF();
	status.relay_out2==SW_ON? LED2_FB_ON() : LED2_FB_OFF();
	status.relay_out3==SW_ON? LED3_FB_ON() : LED3_FB_OFF();
	status.relay_out4==SW_ON? LED4_FB_ON() : LED4_FB_OFF();
}

void sw_sync_status(Switch_Protocol sw)
{
	bool sync_status=false;
	sync_status|=(sw.status.sw_in1!=sw_model.SW_OUT_Status.IN1?true:false);
	sync_status|=(sw.status.sw_in2!=sw_model.SW_OUT_Status.IN2?true:false);
	sync_status|=(sw.status.sw_in3!=sw_model.SW_OUT_Status.IN3?true:false);
	sync_status|=(sw.status.sw_in4!=sw_model.SW_OUT_Status.IN4?true:false);
	if(sync_status)
	{
		OpenOFF_SW_NOResponse(sw.status);
	}
	SW_FB_Status(sw.status);
}
/// @brief lora 开关数据接收函数
/// @param data 数据
/// @param len 数据长度
void Lora_Switch_Recive(uint8_t *data,uint8_t len)
{
	Switch_Protocol sw;
	if(len==sizeof(Switch_Protocol))
	{
		mymemcpy((uint8_t *)&sw,data,len);
		if(sw.id==model_info_handle.general_info.SN)
		{
		  if(sw.type == SW_Control)
		  {
			  OpenOFF_SW(sw.status);
		  }
		  else if(sw.type==SW_Response)
		  {
			  Recive_Switch_Response(sw.status);
		  }
		  else if(sw.type==SW_Heartbeat)
		  {
			  sw_sync_status(sw);
		  }
		  Heartbeat_Receive();
	  }
	}
}
void Send_Switch_Response(Chanle_IN_t status)
{
	Switch_Protocol sw;
	sw.id=model_info_handle.general_info.SN;
	sw.status.relay_out1=status.IN1;
	sw.status.relay_out2=status.IN2;
	sw.status.relay_out3=status.IN3;
	sw.status.relay_out4=status.IN4;
	sw.type=SW_Response;
	User_LoRaSend_Data((uint8_t *)&sw,sizeof(Switch_Protocol));
}

/// @brief 发送开关控制状态
/// @param status 状态
void Send_Switch_Control(Chanle_IN_t sw_in)
{
	Switch_Protocol sw;
	sw.id=model_info_handle.general_info.SN;
	sw.status.sw_in1=sw_in.IN1;
	sw.status.sw_in2=sw_in.IN2;
	sw.status.sw_in3=sw_in.IN3;
	sw.status.sw_in4=sw_in.IN4;
	sw.type=SW_Control;
	
	User_LoRaSend_Data((uint8_t *)&sw,sizeof(Switch_Protocol));
}
/// @brief 查询开关输入状态
/// @param  
/// @return 开关引脚状态
uint8_t GetSW_IN(uint8_t sw_idx)
{
	uint8_t status = 0;
	switch(sw_idx)
	{
		case SW_IN1:status = SW1_IN();break;
		case SW_IN2:status = SW2_IN();break;
		case SW_IN3:status = SW3_IN();break;
		case SW_IN4:status = SW4_IN();break;
	}
	if(status == 0)
	{
		return SW_OFF;
	}
	else
	{
		return SW_ON;
	}
}
/// @brief 开关状态滤波器
/// @param filter 滤波器
/// @param status 状态
/// @param time 时间
/// @return 滤波后的开关状态
uint8_t SW_Filter_State(Switch_Filter_t *filter,uint8_t status,uint8_t time)
{
	if(status!=filter->in_last_status)
	{
		filter->time=0;
		filter->in_last_status=status;
	}
	else
	{
		filter->time+=time;
		if(filter->time>=filter->filter_time)
	  {
			filter->time=filter->filter_time;
			filter->out_status=status;
	  }
	}
	return filter->out_status;
}
/****************************
 * 功能：初始化按键消抖滤波器
****************************/
void Init_SW_Filter(Switch_Filter_t *filter,uint16_t filter_time)
{
	filter->filter_time=filter_time;
	filter->out_status=SW_OFF;
	filter->in_last_status=SW_OFF;
	filter->time=0;
}

//
bool SW_Event_Handle(Switch_Filter_t *filter,Chanle_IN_t *sw_in,uint8_t sw_idx)
{
	bool sw_change=false;
	uint8_t in_status;
	in_status = SW_Filter_State(filter,GetSW_IN(sw_idx),20);    //开关状态
	switch(sw_idx)
	{
		case SW_IN1:
			if(in_status != sw_in->IN1)                    //状态变化
	    {
		    sw_in->IN1 = in_status;
				sw_change=true;
	    }
			break;
		case SW_IN2:
			if(in_status != sw_in->IN2)                    //状态变化
	    {
		    sw_in->IN2 = in_status;
				sw_change=true;
	    }
			break;
		case SW_IN3:
			if(in_status != sw_in->IN3)                    //状态变化
	    {
		    sw_in->IN3 = in_status;
				sw_change=true;
	    }
			break;
		case SW_IN4:
			if(in_status != sw_in->IN4)                    //状态变化
	    {
		    sw_in->IN4 = in_status;
				sw_change=true;
	    }
			break;
	}
	return sw_change;
}

/***************************
*初始化响应重发
****************************/
void Init_Reply_Response(Switch_Retry_t *reply)
{
	reply->response_step=ResPonse_step_success;
	reply->time=0;
	reply->retry_number=0;
	reply->wait_time=500;
}
//接收响应状态
void Recive_Switch_Response(SW_Status status)
{
	SW_FB_Status(status);
	sw_retry.response_step=ResPonse_step_success;
}
/****************************
 *等待响应
****************************/
void Start_Switch_Response_Wait(Switch_Retry_t *retry)
{
	retry->response_step=Response_step_wait;
	retry->time=0;
}
//获取开关状态响应
uint8_t Get_Switch_Response(Switch_Retry_t *retry,uint8_t time)
{
	uint8_t status=0;
	switch(retry->response_step)
	{
		case ResPonse_step_success:   //响应成功
			status=0;
			break;
		case Response_step_wait:
			retry->time+=time;
		  if(retry->time>retry->wait_time)
			{
				retry->time=0;
				status=1;                //响应超时
			}
			break;
		case ResPonse_step_overtime:   
			retry->time+=time;
		  if(retry->time>retry->wait_time)
			{
				if(retry->retry_number<10)
				{
					retry->time=0;
					status=1;              //响应超时
				}
				else
				{
					status=2;
				}
			}
			break;
	}
	return status;
}

/// @brief 开关线程
/// @param paremeter 
void Switch_thread_entry(void *paremeter)
{
	bool sw_change=false;
	Switch_Filter_t sw_filter1;
	Switch_Filter_t sw_filter2;
	Switch_Filter_t sw_filter3;
	Switch_Filter_t sw_filter4;
	
	Init_SW_Filter(&sw_filter1,200);
	Init_SW_Filter(&sw_filter2,200);
	Init_SW_Filter(&sw_filter3,200);
	Init_SW_Filter(&sw_filter4,200);
	
//	Set_LED_DI(SW_OFF);
	Set_LED_DO(SW_OUT1,SW_OFF);
	Set_LED_DO(SW_OUT2,SW_OFF);
	Set_LED_DO(SW_OUT3,SW_OFF);
	Set_LED_DO(SW_OUT4,SW_OFF);
	sw_model.SW_OUT_Status.IN1=SW_OFF;
	sw_model.SW_OUT_Status.IN2=SW_OFF;
	sw_model.SW_OUT_Status.IN3=SW_OFF;
	sw_model.SW_OUT_Status.IN4=SW_OFF;
	sw_model.SW_IN_Status.IN1=SW_OFF;
	sw_model.SW_IN_Status.IN2=SW_OFF;
	sw_model.SW_IN_Status.IN3=SW_OFF;
	sw_model.SW_IN_Status.IN4=SW_OFF;
	Init_Reply_Response(&sw_retry);   //初始化重发管理
	while(1)
	{
		sw_change=false;
		sw_change|=SW_Event_Handle(&sw_filter1,&sw_model.SW_IN_Status,SW_IN1);

		sw_change|=SW_Event_Handle(&sw_filter2,&sw_model.SW_IN_Status,SW_IN2);

		sw_change|=SW_Event_Handle(&sw_filter3,&sw_model.SW_IN_Status,SW_IN3);

		sw_change|=SW_Event_Handle(&sw_filter4,&sw_model.SW_IN_Status,SW_IN4);
		if(sw_change)
		{
			Send_Switch_Control(sw_model.SW_IN_Status);
			Start_Switch_Response_Wait(&sw_retry);
		}
		if(Get_Switch_Response(&sw_retry,20)==1)
		{
			Send_Switch_Control(sw_model.SW_IN_Status);                     //发送开关状态
		}
		rt_thread_mdelay(20);
	}
}
